package com.putable.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * The class CGW Server opens up the socket and listens for connection from clients.
 * @author Event Horizon
 *
 */
public class CGWServer {
        
        /** Server default port number */
        private static final int DEFAULT_PORT_NUMBER = 44455;

        /** The instance of the server socket **/
        private ServerSocket CGWServerSocket;

        /** The instance of the client handler. **/
        private CGWClientHandler clientHandler;


        /**
         * Instantiates a copy of the JWorld Server
         */
        public CGWServer() {

                try {
                        connectPort();
                } catch (IOException e) {
                        System.err.println("Cannot open port");
                        System.exit(1);
                }

                clientHandler = new CGWClientHandler();
                Thread clientHandlerThread = new Thread();
                clientHandlerThread.setDaemon(true);
                clientHandlerThread.start();

                acceptConnections(CGWServerSocket, clientHandler);

                System.out
                                .println("CGWServer: No more incoming connections allowed");

                try {
                        CGWServerSocket.close(); // Do not accept further connections
                } catch (IOException e) {
                        e.printStackTrace();
                }

        }
        

        /**
         * Accepts connections. And then adds the client to the client handler.
         * 
         * @param server
         *            the socket connection for the server
         * @param clientHandler
         *            the client handler adds and manages the clients
         */
        private void acceptConnections(ServerSocket server,
                        CGWClientHandler clientHandler) {
                int i = 0;
                while (true) {
                        Socket in = null;
                        try {
                                in = server.accept();
                                clientHandler.addClient(new CGWClientProxy(in, this));
                        } catch (IOException e) {
                                System.out
                                                .println("CGWServer: Could not establish connection with client");
                        }
                        i++;
                }
        }

        /**
         * Connect port will open a new socket connection and bind it to the port
         * number.
         * 
         * @throws IOException
         */
        public void connectPort() throws IOException {
                if (CGWServerSocket == null)
                        CGWServerSocket = new ServerSocket();

                CGWServerSocket.bind(new InetSocketAddress(DEFAULT_PORT_NUMBER));
        }

        /**
         * getServer returns a copy of the Server Socket for testing purposes
         * 
         * @return the server socket
         */
        public ServerSocket getServerSocket() {
                return CGWServerSocket;
        }

        /**
         * Starts a new CGWServer.
         */
        public static void main(String[] args) {
                new CGWServer();
        }
}
